home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1990 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* z2path.c */
- /* Level 2 user path and rectangle operators */
- #include "ghost.h"
- #include "errors.h"
- #include "oper.h"
- #include "state.h"
- #include "stream.h"
- #include "i2num.h"
-
- /* .rectappend */
- int
- zrectappend(register ref *op)
- { int npop, code;
- stream st;
- float pq[4];
- int i;
- ref rnum;
- switch ( r_type(op) )
- {
- case t_array: case t_string:
- code = sread_num_array(&st, op);
- if ( code < 0 ) return code;
- npop = 1;
- break;
- default: /* better be 4 numbers */
- sread_string(&st, (byte *)(op - 3), sizeof(ref) * 4);
- st.num_format = num_array;
- npop = 4;
- break;
- }
- while ( 1 )
- { for ( i = 0; i < 4; i++ )
- { switch ( code = sget_encoded_number(&st, &rnum) )
- {
- case t_integer:
- pq[i] = rnum.value.intval;
- break;
- case t_real:
- pq[i] = rnum.value.realval;
- break;
- case t_null:
- if ( i != 0 ) return e_syntaxerror;
- pop(npop);
- return 0;
- default: /* code < 0 */
- return code;
- }
- }
- /* Force the vertices into counter-clockwise order, */
- /* by requiring width >= 0, height >= 0. */
- if ( pq[2] < 0 ) pq[0] += pq[2], pq[2] = -pq[2];
- if ( pq[3] < 0 ) pq[1] += pq[3], pq[3] = -pq[3];
- if ( (code = gs_moveto(igs, pq[0], pq[1])) < 0 ||
- (code = gs_rlineto(igs, pq[2], 0.0)) < 0 ||
- (code = gs_rlineto(igs, 0.0, pq[3])) < 0 ||
- (code = gs_rlineto(igs, -pq[2], 0.0)) < 0 ||
- (code = gs_closepath(igs)) < 0
- )
- return code;
- }
- }
-
- /* User path operator codes */
- typedef enum {
- upath_setbbox = 0,
- upath_moveto = 1,
- upath_rmoveto = 2,
- upath_lineto = 3,
- upath_rlineto = 4,
- upath_curveto = 5,
- upath_rcurveto = 6,
- upath_arc = 7,
- upath_arcn = 8,
- upath_arct = 9,
- upath_closepath = 10,
- upath_ucache = 11
- } upath_op;
- #define upath_op_max 11
- #define upath_repeat 32
- static byte up_nargs[upath_op_max + 1] =
- { 4, 2, 2, 2, 2, 6, 6, 5, 5, 5, 0, 0 };
- #define zp(proc) extern int proc(P1(ref *));
- zp(zsetbbox); zp(zmoveto); zp(zrmoveto);
- zp(zlineto); zp(zrlineto); zp(zcurveto); zp(zrcurveto);
- zp(zarc); zp(zarcn); zp(zarct); zp(zclosepath); zp(zucache);
- #undef zp
- static int (*up_ops[upath_op_max + 1])(P1(ref *)) =
- { zsetbbox, zmoveto, zrmoveto, zlineto, zrlineto,
- zcurveto, zrcurveto, zarc, zarcn, zarct,
- zclosepath, zucache
- };
-
- /* uappend */
- int
- zuappend(register ref *op)
- { /****** ROUND tx AND ty ******/
- /****** ALLOW PACKED ARRAY ******/
- check_array(*op);
- if ( op->size == 2 && r_type(op->value.refs + 1) == t_string )
- { /* 1st element is operators, 2nd is operands */
- stream st;
- int code;
- int repcount = 1;
- byte *opp;
- uint ocount;
- code = sread_num_array(&st, op->value.refs);
- if ( code < 0 ) return code;
- opp = op->value.refs[1].value.bytes;
- ocount = op->value.refs[1].size;
- while ( ocount-- )
- { byte opx = *opp++;
- if ( opx > 32 )
- repcount = opx - 32;
- else if ( opx > upath_op_max )
- return e_typecheck;
- else /* operator */
- { do
- { byte opargs = up_nargs[opx];
- while ( opargs-- )
- { push(1);
- code = sget_encoded_number(&st, op);
- switch ( code )
- {
- case t_integer: case t_real:
- /***** SET TYPE *****/
- break;
- default:
- return e_typecheck;
- }
- }
- code = (*up_ops[opx])(op);
- if ( code < 0 ) return code;
- op = osp; /* resync */
- }
- while ( --repcount );
- repcount = 1;
- }
- }
- }
- else
- { /* Ordinary executable array */
- ref *opp = op->value.refs;
- uint ocount = op->size;
- int argcount = 0;
- int (*oproc)(P1(ref *));
- int opx, code;
- for ( ; ocount--; opp++ )
- switch ( r_type(opp) )
- {
- case t_integer: case t_real:
- argcount++;
- push(1);
- *op = *opp;
- break;
- case t_name:
- if ( !r_has_attrs(op, a_executable) )
- return e_typecheck;
- /****** LOOK UP IN systemdict ******/
- /****** MUST BE AN OPERATOR -> oproc ******/
- goto xop;
- case t_operator:
- if ( !r_has_attrs(op, a_executable) )
- return e_typecheck;
- oproc = op->value.opproc;
- xop: for ( opx = 0; opx <= upath_op_max; opx++ )
- if ( oproc == up_ops[opx] ) break;
- if ( opx > upath_op_max || argcount != up_nargs[opx] )
- return e_typecheck;
- code = (*oproc)(op);
- if ( code < 0 ) return code;
- op = osp; /* resync ostack pointer */
- argcount = 0;
- break;
- default:
- return e_typecheck;
- }
- }
- pop(1);
- return 0;
- }
-
- /* ------ Initialization procedure ------ */
-
- void
- z2path_op_init()
- { static op_def my_defs[] = {
- {"1.rectappend", zrectappend},
- {"1uappend", zuappend},
- op_def_end
- };
- z_op_init(my_defs);
- }
-